package com.owc.service.impl.admin;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.owc.common.enums.ExceptionEnum;
import com.owc.common.exception.BadRequestException;
import com.owc.common.tool.BeanUtils;
import com.owc.common.Const.Const;
import com.owc.dao.TokenBalanceMapper;
import com.owc.dao.TokenMapper;
import com.owc.dao.UserMapper;
import com.owc.dao.UserWalletAddressMapper;
import com.owc.domain.BaseResult;
import com.owc.domain.dto.BalanceDTO;
import com.owc.domain.dto.admin.*;
import com.owc.domain.entity.Token;
import com.owc.domain.entity.User;
import com.owc.domain.entity.UserWalletAddress;
import com.owc.domain.vo.admin.QueryUser;
import com.owc.domain.vo.app.TokenVo;
import com.owc.service.WalletServer;
import com.owc.service.admin.FundsService;
import com.owc.service.admin.UserManageService;
import com.owc.service.app.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Author Jackies
 * @Date 2019/12/9 22:51
 * @Description TODO://
 **/
@Service
@Slf4j
public class UserManageServiceImpl implements UserManageService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private TokenMapper tokenMapper;
    @Resource
    private UserWalletAddressMapper userWalletAddressMapper;

    @Autowired
    private UserService userService;
    @Autowired
    private TokenBalanceMapper tokenBalanceMapper;
    @Autowired
    private WalletServer walletServer;
    @Autowired
    private FundsService fundsService;

    @Override
    public BaseResult<List<UserBeanDTO>> userList(QueryUser queryUser) {
        PageHelper.startPage(queryUser.getPageIndex(),queryUser.getPageSize());
        List<User> userList = userMapper.selectByModel(queryUser);
        if(userList == null){
            return BaseResult.success(new ArrayList<>(),0L);
        }
        PageInfo<User> pageInfo = new PageInfo<>(userList);

        List<UserBeanDTO> userBeanDTOS = new ArrayList<>();
        userList.forEach(user -> userBeanDTOS.add(new UserBeanDTO().convertFrom(user)));
        return BaseResult.success(userBeanDTOS,pageInfo.getTotal());
    }

    @Override
    public UserDetail userDetail(Long userId) {
        Optional<User> optUser = userService.selectById(userId);
        if(!optUser.isPresent()){
            throw new BadRequestException(ExceptionEnum.USER_INVALID_ERR);
        }
        List<AccountInfo> accountInfos = tokenBalanceMapper.selectUserTokenListWithAdmin(optUser.get().getId());
        //实时刷新钱包余额
        accountInfos.forEach(accountInfo -> fundsService.updateUserWalletBalance(accountInfo.getWalletAddress(),accountInfo.getTokenName()));
        //再次获取最新余额
        accountInfos = tokenBalanceMapper.selectUserTokenListWithAdmin(optUser.get().getId());
        return new UserDetail(BeanUtils.transformFrom(optUser.get(),UserDetail.BasisInfo.class),accountInfos);
    }

    @Override
    public BalanceDTO getPlatformBalance(Long tokenId) throws Exception {
        return getWalletBalance(new TokenVo(tokenId,-1L));
    }

    @Override
    public BalanceDTO getWalletBalance(TokenVo tokenVo) throws Exception {

        String chainName,address = null;

        Token token = tokenMapper.selectByPrimaryKey(tokenVo.getTokenId());
        Assert.notNull(token,"异常的代币选项");

//        if(token.getParentId() != -1){
//            Token parentToken = tokenMapper.selectByPrimaryKey(token.getParentId());
//            chainName = parentToken.getTokenName();
//        }else{
        chainName = token.getTokenName();
//        }

        //获取钱包地址信息
        UserWalletAddress walletAddress = walletServer.getUserAddressInfo(tokenVo.getUserId());

        if(walletAddress != null){
            address = walletAddress.getEth();
        }


        //调用钱包服务获取最新余额
        try {
            BigDecimal balance = walletServer.getPlatformBalance(Const.ETH,chainName,address);
            return new BalanceDTO(balance,token.getTokenName());
        } catch (Exception e) {
            log.error("获取钱包余额失败 exMsg:{}",e.getMessage());
            e.printStackTrace();
            throw new Exception(ExceptionEnum.BAD_REQUEST_ERR.getMessage());
        }
    }

    @Override
    public GasRecommend getRecommendGas() {
        try {
            return new GasRecommend(walletServer.getRecommendGas().toPlainString());
        } catch (Exception e) {
            throw new BadRequestException(ExceptionEnum.BAD_REQUEST_ERR);
        }
    }

    @Override
    public String getUserEthAddress(Long userId) {
        UserWalletAddress walletAddress = userWalletAddressMapper.selectByUserId(userId);
        if(walletAddress == null) {
            throw new BadRequestException(ExceptionEnum.USER_INFO_ERR);
        }
        return walletAddress.getEth();
    }

    @Override
    public MatchUserDTO getUserInfoByPhone(String phone) {

        User user = userService.selectByPhone(phone)
                .orElseThrow(() -> new BadRequestException("Match failed"));

        MatchUserDTO matchUserDTO = new MatchUserDTO();
        matchUserDTO.setEbc_balance(tokenBalanceMapper.selectByUserIdAndTokenName(user.getId(),"EBC").getBalance().toPlainString());
        matchUserDTO.setOwc_balance(tokenBalanceMapper.selectByUserIdAndTokenName(user.getId(),"OWC").getBalance().toPlainString());
        matchUserDTO.setPhone(user.getPhone());
        matchUserDTO.setUserId(user.getId());

        return matchUserDTO;
    }
}
